﻿// Principia
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;

namespace Principia.Core.Parsing.ContextFree.LR
{
    public class ParserConstructionException : Exception
    {
        public ParserConstructionException(string Message)
            : base("Could not construct a parser because: " + Message)
        {
        }
    }

    public class ShiftReduceException : ParserConstructionException
    {
        public ShiftReduceException(ITerminal Term, IEnumerable<Production> Productions)
            : base(string.Format("Shift/reduce error in grammar: could either shift {0}, or reduce by one of:\n    {1}",
                                 Term, Productions.Join("\n    ")))
        {
            this.Term = Term;
            this.Productions = Productions;
        }

        public ITerminal Term { get; private set; }
        public IEnumerable<Production> Productions { get; private set; }
    }

    public class ReduceReduceException : ParserConstructionException
    {
        public ReduceReduceException(IEnumerable<Production> Productions)
            : base(string.Format("Reduce/reduce error in grammar: could reduce by any of:\n    {0}",
                                 Productions.Join("\n    ")))
        {
            this.Productions = Productions;
        }

        public IEnumerable<Production> Productions { get; private set; }
    }
}